package com.ly.system.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson.JSONObject;
import com.ly.common.core.bean.vo.TreeVO;
import com.ly.gen.entity.GenTable;
import com.ly.gen.utils.GenUtils;
import com.ly.system.system.bean.entity.SysDept;
import com.ly.system.system.bean.entity.SysPermission;
import com.ly.system.system.bean.vo.MenuVO;
import org.apache.commons.lang3.ObjectUtils;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 公共组装tree
 *
 * @author luoyun
 * @Date: 2025/5/25 20:54
 * @Note:
 */
public class TreeUtils {

    public static List<TreeVO> getTreeVoByDeptList(List<SysDept> list) {
        return getTreeVoByDeptList(list, true);
    }

    /**
     * 组装部门树
     *
     * @param list
     * @param treeFlag: 是否转化成树
     * @return
     */
    public static List<TreeVO> getTreeVoByDeptList(List<SysDept> list, Boolean treeFlag) {
        List<TreeVO> vos = new ArrayList<>();
        if (CollUtil.isEmpty(list)) {
            return vos;
        }
        // 封装基础树
        List<TreeVO> allList = list.stream().map(
                n -> new TreeVO(n.getId(), n.getOrgName(), n.getParentId(), ObjUtil.equals(n.getIzLeaf(), 1))
        ).collect(Collectors.toList());
        if (!treeFlag) {
            return allList;
        }
        // 组装成树结构，所有父级map，key为组织编码，value为组织对象
        Map<String, TreeVO> map =
                allList.stream().collect(Collectors.toMap(TreeVO::getKey, o -> o, (n1, n2) -> n1));
        // 实现树形结构
        allList.stream().forEach(vo -> {
            TreeVO parent = map.get(vo.getParentKey());
            if (ObjectUtils.isEmpty(parent)) {
                vos.add(vo);
            } else {
                Collection<TreeVO> children = parent.getChildren();
                if (CollUtil.isEmpty(children)) {
                    parent.setChildren(new ArrayList<>());
                }
                // 此处不能用  children.add(vo); 否则孩子为空
                parent.getChildren().add(vo);
            }
        });
        return vos;
    }

    /**
     * 组装菜单树
     *
     * @param menuList：菜单元数据
     * @return
     */
    public static List<MenuVO> getMenuTreeListByMap(List<MenuVO> menuList) {
        // 1. 按 parentId 分组（用 Map 存储所有节点，方便快速查找）
        Map<String, List<MenuVO>> allMap = menuList.stream().collect(Collectors.groupingBy(MenuVO::getParentId));
        // 2. 找出所有根节点（parentId 为 null 的节点）
        List<MenuVO> roots = allMap.getOrDefault("", new ArrayList<>());
        // 3. 递归构建子树（用栈模拟递归）
        for (MenuVO root : roots) {
            buildChildrenMenu(root, allMap);
        }
        return roots;
    }

    /**
     * 递归构建子节点（用栈模拟递归，避免栈溢出）
     *
     * @param root   父节点
     * @param allMap
     */
    private static void buildChildrenMenu(MenuVO root, Map<String, List<MenuVO>> allMap) {
        List<MenuVO> children = allMap.get(root.getId());
        if (children != null) {
            root.setChildren(children);
            for (MenuVO child : children) {
                buildChildrenMenu(child, allMap); // 递归处理子节点
            }
        }
    }

    /**
     * 根据父id，找到所有级联的id
     */
    public static List<SysPermission> getChildMenuList(List<SysPermission> menuList, String ParentId) {
        List<SysPermission> result = new ArrayList<>();
        for (SysPermission n : menuList) {
            if (ParentId.equals(n.getParentId())) {
                // 找到直接子节点，加入结果列表
                result.add(n);
                // 递归查找该子节点的下级
                result.addAll(getChildMenuList(menuList, n.getId()));
            }
        }
        return result;
    }

    /**
     * 组装菜单树-todo:
     *
     * @param menuList：菜单元数据
     * @param parentId：菜单父级id
     * @return
     */
    public static List getTreeVoByMenuList(List<MenuVO> menuList, String parentId) {
        List<MenuVO> collect = menuList.stream().filter(n -> ObjUtil.equals(parentId, n.getParentId())).collect(Collectors.toList());
        return null;
    }

    /**
     * 指定文件夹的树形结构
     */
    public static List<TreeVO> buildTreeFromFolder(String folderPath, GenTable table) {
        File rootFile = FileUtil.file(folderPath);
        if (!rootFile.exists()) {
            throw new IllegalArgumentException("文件夹路径不存在: " + folderPath);
        }
        if (!rootFile.isDirectory()) {
            throw new IllegalArgumentException("路径不是文件夹: " + folderPath);
        }
        // 根节点的 key 可以用文件夹路径，或者固定一个值，title 是文件夹名
        TreeVO treeVO = buildTreeVO(rootFile, null, table);
        return Arrays.asList(new TreeVO[]{treeVO});
    }

    /**
     * 递归构建 TreeVO
     */
    private static TreeVO buildTreeVO(File file, String parentKey, GenTable table) {
        String extConfigJson = table.getExtConfigJson();
        JSONObject jsonObject = JSONObject.parseObject(extConfigJson);
        // 原始路径E:\workspace-gitee\lely-boot-cloud\lely-boot-server\lely-system-start\target\classes\gen\code-template-online\default\java\${bussiPackage}\${entityPackage}\entity\${entityName}.javai
        // 原始路径E:\workspace-gitee\lely-boot-cloud\lely-boot-server\lely-system-start\target\classes\gen\code-template-online\default\java\${bussiPackage}\${entityPackage}
        String path = file.getAbsolutePath();

        TreeVO node = new TreeVO(
                jsonObject.getString(path) == null ? path : jsonObject.getString(path),
                GenUtils.getRealPath(file.getName(), table),
                parentKey,
                !file.isDirectory());
        if(file.getName().endsWith(".7z")){
            node.setDisabled(true);
        }
        // 如果是文件夹，则递归添加子节点
        if (file.isDirectory()) {
            File[] children = file.listFiles();
            if (children != null) {
                List<TreeVO> childNodes = new ArrayList<>();
                for (File child : children) {
                    TreeVO childNode = buildTreeVO(child, path, table); // 当前文件的 path 作为 parentKey
                    childNodes.add(childNode);
                }
                node.setChildren(childNodes);
            }
        }
        return node;
    }
}
